package com.tabjin.rfidsocket.service.access.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Preconditions;
import com.tabjin.rfidsocket.common.org.n3r.idworker.Sid;
import com.tabjin.rfidsocket.common.utils.BeanValidator;
import com.tabjin.rfidsocket.common.utils.PagedGridResult;
import com.tabjin.rfidsocket.exception.ParamException;
import com.tabjin.rfidsocket.mapper.mapper.ArchBuildingMapper;
import com.tabjin.rfidsocket.mapper.mapper.ArchHouseMapper;
import com.tabjin.rfidsocket.pojo.ArchHouse;
import com.tabjin.rfidsocket.pojo.bo.access.ArchHouseBO;
import com.tabjin.rfidsocket.pojo.vo.access.ArchHouseVO;
import com.tabjin.rfidsocket.service.access.ArchHouseService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author tabjin
 * create at 2021/1/18 16:54
 * @program rfid_socket
 * @description
 */
@Service
public class ArchHouseServiceImpl implements ArchHouseService {
    private static final Logger logger = LoggerFactory.getLogger(ArchHouseServiceImpl.class);

    private final ArchHouseMapper archHouseMapper;
    private final Sid sid;
    private final ArchBuildingMapper archBuildingMapper;

    public ArchHouseServiceImpl(ArchHouseMapper archHouseMapper, Sid sid, ArchBuildingMapper archBuildingMapper) {
        this.archHouseMapper = archHouseMapper;
        this.sid = sid;
        this.archBuildingMapper = archBuildingMapper;
    }

    @Override
    public List<ArchHouse> getHousesByBuildingId(Integer buildingId) {
        Example example = new Example(ArchHouse.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("whichBuilding", buildingId);
        List<ArchHouse> archHouses = archHouseMapper.selectByExample(example);
        return archHouses;
    }

    @Override
    public List<ArchHouse> getHousesByBuildingUnit(String buildingUnit) {
        Example example = new Example(ArchHouse.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("whichBuilding", buildingUnit);
        return archHouseMapper.selectByExample(example);
    }

    /**
     * 添加房屋
     *
     * @param archHouseBO
     */
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void add(ArchHouseBO archHouseBO) {
        BeanValidator.check(archHouseBO);
        // 查重
        if (checkExist(archHouseBO.getWhichBuilding(), archHouseBO.getName())) {
            logger.error("当前楼栋存在相同的房屋名称");
            throw new ParamException("当前楼栋存在相同的房屋名称");
        }

        ArchHouse archHouse = ArchHouse.builder()
//                .id(sid.nextShort())
                .name(archHouseBO.getName())
                .status(archHouseBO.getStatus())
                .checkIn(archHouseBO.getCheckIn())
                .floor(archHouseBO.getFloor())
                .whichBuilding(archHouseBO.getWhichBuilding())
                .area(archHouseBO.getArea())
                .setArea(archHouseBO.getSetArea())
                .unitType(archHouseBO.getUnitType())
                .constructionAge(archHouseBO.getConstructionAge())
                .towards(archHouseBO.getTowards())
                .decoration(archHouseBO.getDecoration())
                .isElevator(archHouseBO.getIsElevator())
                .propertyRight(archHouseBO.getPropertyRight())
                .level(archHouseBO.getLevel())
                .tag(archHouseBO.getTag())
                .visibleToResidents(archHouseBO.getVisibleToResidents())
                .saleStatus(archHouseBO.getSaleStatus())
                .saleTime(archHouseBO.getSaleTime())
                .billingStartTime(archHouseBO.getBillingStartTime())
                .standardAddressCoding(archHouseBO.getStandardAddressCoding())
                .standardProjectCode(archHouseBO.getStandardProjectCode())
                .deed(archHouseBO.getDeed())
                .leaseContract(archHouseBO.getLeaseContract())
                .administratorId(archHouseBO.getAdministratorId())
                .createTime(archHouseBO.getCreateTime())
                .operator("张进")
                .operatorIp("127.0.0.1")
                .build();

        archHouseMapper.insertSelective(archHouse);
    }

    /**
     * 删除房屋
     *
     * @param houseId
     */
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void delete(Integer houseId) {
        archHouseMapper.deleteByPrimaryKey(houseId);
    }

    /**
     * 更新房屋
     *
     * @param archHouseBO
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public ArchHouseVO update(ArchHouseBO archHouseBO) {
        BeanValidator.check(archHouseBO);
        // 查重
        if (checkExist(archHouseBO.getWhichBuilding(), archHouseBO.getName())) {
            logger.error("当前楼栋存在相同的房屋名称");
            throw new ParamException("当前楼栋存在相同的房屋名称");
        }

        ArchHouse before = archHouseMapper.selectByPrimaryKey(archHouseBO.getId());
        Preconditions.checkNotNull(before, "待删除的房屋不存在");

        ArchHouse after = ArchHouse.builder()
                .name(archHouseBO.getName())
                .status(archHouseBO.getStatus())
                .checkIn(archHouseBO.getCheckIn())
                .floor(archHouseBO.getFloor())
                .whichBuilding(archHouseBO.getWhichBuilding())
                .area(archHouseBO.getArea())
                .setArea(archHouseBO.getSetArea())
                .unitType(archHouseBO.getUnitType())
                .constructionAge(archHouseBO.getConstructionAge())
                .towards(archHouseBO.getTowards())
                .decoration(archHouseBO.getDecoration())
                .isElevator(archHouseBO.getIsElevator())
                .propertyRight(archHouseBO.getPropertyRight())
                .level(archHouseBO.getLevel())
                .tag(archHouseBO.getTag())
                .visibleToResidents(archHouseBO.getVisibleToResidents())
                .saleStatus(archHouseBO.getSaleStatus())
                .saleTime(archHouseBO.getSaleTime())
                .billingStartTime(archHouseBO.getBillingStartTime())
                .standardAddressCoding(archHouseBO.getStandardAddressCoding())
                .standardProjectCode(archHouseBO.getStandardProjectCode())
                .deed(archHouseBO.getDeed())
                .leaseContract(archHouseBO.getLeaseContract())
                .administratorId(archHouseBO.getAdministratorId())
                .createTime(archHouseBO.getCreateTime())
                .operator("张进")
                .operatorIp("127.0.0.1")
                .build();

        archHouseMapper.updateByPrimaryKey(after);

        ArchHouseVO vo = new ArchHouseVO();
        BeanUtils.copyProperties(after, vo);
        return vo;
    }

    /**
     * 获取所有房屋
     *
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public PagedGridResult getAll(Integer page, Integer pageSize) {
        PageHelper.startPage(page, pageSize);
        List<ArchHouse> archHouseList = archHouseMapper.selectAll();

        List<ArchHouseVO> archHouseVOList = archHouseList.stream().map(item -> {
            ArchHouseVO vo = new ArchHouseVO();
            BeanUtils.copyProperties(item, vo);
            return vo;
        }).collect(Collectors.toList());
        return setPagesGrid(archHouseVOList, page);
    }

    /**
     * 获取单个房屋
     *
     * @param houseId
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public ArchHouseVO getItem(Integer houseId) {
        ArchHouse archHouse = archHouseMapper.selectByPrimaryKey(houseId);
        ArchHouseVO vo = new ArchHouseVO();
        BeanUtils.copyProperties(archHouse, vo);
        return vo;
    }

    /**
     * 查重
     *
     * @param whichBuilding
     * @param name
     * @return
     */
    boolean checkExist(Integer whichBuilding, String name) {
        Example example = new Example(ArchHouse.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("whichBuilding", whichBuilding);
        criteria.andEqualTo("name", name);
        return archHouseMapper.selectCountByExample(example) > 0;
    }

    /**
     * 封装分页助手
     *
     * @param list
     * @param page
     * @return
     */
    private PagedGridResult setPagesGrid(List<?> list, Integer page) {
        PageInfo pageList = new PageInfo<>(list);
        PagedGridResult grid = new PagedGridResult();
        grid.setPage(page);
        grid.setRows(list);
        grid.setTotal(pageList.getPages());
        grid.setRecords(pageList.getTotal());
        return grid;
    }
}
